﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartSpace.OrganizationalStructure
{
    public partial class OrganizationService : IOrganizationService
    {
        public bool SaveOrganizationType(OrganizationType type)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                if (string.IsNullOrEmpty(context.Set<OrganizationType>().Where(p => p.Code == type.Code).Select(p => p.Code).SingleOrDefault()))
                {
                    context.Set<OrganizationType>().Add(type);
                }
                else
                {
                    context.Entry(type).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public bool DeleteOrganizationType(OrganizationType type)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                if (string.IsNullOrEmpty(context.Set<OrganizationType>().Where(p => p.Code == type.Code).Select(p => p.Code).SingleOrDefault()))
                {
                    return true;
                }
                else
                {
                    context.Entry(type).State = System.Data.Entity.EntityState.Deleted;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public bool DeleteOrganizationType(string code)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                OrganizationType type = context.Set<OrganizationType>().Where(p => p.Code == code).SingleOrDefault();
                if (type == null)
                {
                    return true;
                }
                else
                {
                    context.Entry(type).State = System.Data.Entity.EntityState.Deleted;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public bool IncludeSubOrganizationType(string code, string subCode)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                if (context.Set<OrganizationTypeRelation>().Where(p => p.ParentCode == code && p.SubCode == subCode).Select(p => p.Id).SingleOrDefault() == default(Guid))
                {
                    return true;
                }
                else
                {
                    OrganizationTypeRelation relation = new OrganizationTypeRelation();
                    relation.Id = Guid.NewGuid();
                    relation.ParentCode = code;
                    relation.SubCode = subCode;
                    context.Set<OrganizationTypeRelation>().Add(relation);
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public bool RemoveSubOrganizationType(string code, string subCode)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                OrganizationTypeRelation relation = context.Set<OrganizationTypeRelation>().Where(p => p.ParentCode == code && p.SubCode == subCode).SingleOrDefault();
                if(relation == null)
                {
                    return true;
                }
                else
                {
                    context.Entry(relation).State = System.Data.Entity.EntityState.Deleted;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public OrganizationType GetOrganizationType(string code)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                return context.Set<OrganizationType>().Where(p => p.Code == code).SingleOrDefault();
            }
        }

        public List<OrganizationType> GetSubOrganizationTypes(string code)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                return context.Set<OrganizationType>()
                    .Join(context.Set<OrganizationTypeRelation>().Where(p=>p.ParentCode == code),
                        ot => ot.Code,
                        otr => otr.SubCode,
                        (ot, otr) => ot)
                    .ToList();
            }
        }
    }
}
